package com.sp.scmdb.serviceImpl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.sp.scmdb.bean.ReaderBean;
import com.sp.scmdb.bean.SecurityTrainingBean;
import com.sp.scmdb.bean.UserBean;
import com.sp.scmdb.common.CommonParamter;
import com.sp.scmdb.dao.AreaDao;
import com.sp.scmdb.dao.EmployeeDao;
import com.sp.scmdb.dao.LabelReadingMachineDao;
import com.sp.scmdb.dao.MapDao;
import com.sp.scmdb.dao.ReaderAlarmDao;
import com.sp.scmdb.entity.Area;
import com.sp.scmdb.entity.Employee;
import com.sp.scmdb.entity.LabelReadingMachine;
import com.sp.scmdb.entity.Map;
import com.sp.scmdb.entity.Reader_Alarm;
import com.sp.scmdb.entity.SecurityTraining;
import com.sp.scmdb.service.LogService;
import com.sp.scmdb.service.ReaderService;
import com.sp.scmdb.spring.ApplicationContext;
import com.sp.scmdb.utils.GroupList;
import com.sp.scmdb.webservice.model.ReaderModel;
import com.sp.scmdb.webservice.model.ReturnResponse;
import com.sp.scmdb.webservice.service.UploadDataService;
import com.sp.scmdb.webservice.suport.CastorSerializer;

@Service("readerService")
public class ReaderServiceImpl implements ReaderService {

	private static Log log = LogFactory.getLog(ReaderServiceImpl.class);
	private LabelReadingMachineDao labelReadingMachineDao;
	private MapDao mapDao;
	private AreaDao areaDao;
	private ReaderAlarmDao raDao;
	private LogService logs;
	private EmployeeDao employeeDao;

	@Required
	public void setRaDao(ReaderAlarmDao raDao) {
		this.raDao = raDao;
	}

	@Required
	public void setLogs(LogService logs) {
		this.logs = logs;
	}

	@Autowired
	public void setAreaDao(AreaDao areaDao) {
		this.areaDao = areaDao;
	}

	@Autowired
	public void setLabelReadingMachineDao(LabelReadingMachineDao labelReadingMachineDao) {
		this.labelReadingMachineDao = labelReadingMachineDao;
	}

	@Autowired
	public void setMapDao(MapDao mapDao) {
		this.mapDao = mapDao;
	}
	@Autowired
	public void setEmployeeDao(EmployeeDao employeeDao) {
		this.employeeDao = employeeDao;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true,isolation=Isolation.READ_UNCOMMITTED)
	public ReaderBean queryReaderAll(ReaderBean readerBean, ReaderBean oldReaderBean) {
		List<LabelReadingMachine> lists = Lists.newArrayList();
		if (readerBean.equals(oldReaderBean)) {
			lists = oldReaderBean.getAllList();
		} else {
			StringBuilder Hql = new StringBuilder("from LabelReadingMachine where 1=1 ");
			if (StringUtils.isNotEmpty(readerBean.getLrmName())) {
				Hql.append(" and lrmName like '%" + readerBean.getLrmName() + "%'");
			}
			if (StringUtils.isNotEmpty(readerBean.getLrmState())) {
				Hql.append(" and lrmState='" + readerBean.getLrmState() + "'");
			}
			if (StringUtils.isNotEmpty(readerBean.getLrmType())) {
				Hql.append(" and lrmType='" + readerBean.getLrmType() + "'");
			}
			lists = labelReadingMachineDao.queryByLrmDetail(Hql.toString());
		}
		if (CollectionUtils.isNotEmpty(lists)) {
			readerBean.setAllList(lists);
			readerBean.setList(lists.subList(readerBean.getCurrentRow(), readerBean.getLastRow()));
		}
		return readerBean;
	}

	@Transactional(readOnly = true)
	public ReaderBean queryReaderByID(String pid) {
		StringBuilder Hql = new StringBuilder("from LabelReadingMachine where 1=1 ");
		ReaderBean readerBean = null;
		SecurityTrainingBean trainingBean = null;
		Employee employee = null;
		if (StringUtils.isNotEmpty(pid)) {
			Hql.append(" and id='" + pid + "'");
			List<LabelReadingMachine> list = Lists.newArrayList();
			list = labelReadingMachineDao.queryByLrmDetail(Hql.toString());
			if (CollectionUtils.isNotEmpty(list)) {
				readerBean = new ReaderBean();
				LabelReadingMachine readerMachine = list.get(0);
				readerBean.setId(readerMachine.getId());
				readerBean.setLrmID(readerMachine.getLrmID());
				readerBean.setLrmName(readerMachine.getLrmName());
				readerBean.setLrmType(String.valueOf(readerMachine.getLrmType()));
				readerBean.setLrmX(readerMachine.getLrmX());
				readerBean.setLrmY(readerMachine.getLrmY());
				readerBean.setRmk(readerMachine.getRmk());
				readerBean.setLrmTime(readerMachine.getLrmTime());
				readerBean.setMapID(new Integer(readerMachine.getMapID()).toString());
				readerBean.setLrmRadius(readerMachine.getLrmRadius());
				readerBean.setMonitorDaySecurity(readerMachine.getMonitorDaySecurity());
				readerBean.setDangerousMans(readerMachine.getDangerousMans());
				if(StringUtils.isNotEmpty(readerMachine.getDangerousMans())) {
					String[] dangerousMans = readerMachine.getDangerousMans().split(",");
					String dangerousMansName = "";
					for(int j = 0; j < dangerousMans.length; j++) {
						employee = employeeDao.getById(Integer.parseInt(dangerousMans[j]));
						dangerousMansName += employee.getEmpName() + ",";
					}
					if(StringUtils.isNotEmpty(dangerousMansName)) {
						dangerousMansName = dangerousMansName.substring(0, dangerousMansName.length() - 1);
					}
					readerBean.setDangerousMansName(dangerousMansName);
				}
				trainingBean = new SecurityTrainingBean();
				if(readerMachine.getSecurityTraining() != null) {
					trainingBean.setSysId(readerMachine.getSecurityTraining().getSysId());
					trainingBean.setTitle(readerMachine.getSecurityTraining().getTitle());
				}
				readerBean.setSecurityTraining(trainingBean);
				readerBean.setPreviousReaders(readerMachine.getPreviousReaders());
				readerBean.setBehindReaders(readerMachine.getBehindReaders());
				readerBean.setOftenHoursSendSMS(readerMachine.getOftenHoursSendSMS());
			}
		}
		return readerBean;
	}

	@Transactional(readOnly = true)
	public List<Map> queryMapAll() {
		StringBuilder Hql = new StringBuilder("from Map where isUsed=1");
		return mapDao.findMapByIsUse(Hql.toString());
	}

	@Transactional
	public String newReader(ReaderBean t, UserBean user) {
		String result = "3";
		StringBuffer Hql = new StringBuffer("from LabelReadingMachine where 1=1 ");
		Hql.append("and lrmID=").append(t.getLrmID()).append("");
		List<LabelReadingMachine> list = labelReadingMachineDao.queryHql(Hql.toString());
		if (CollectionUtils.isEmpty(list)) {
			LabelReadingMachine reader = new LabelReadingMachine();
			reader.setLrmID(t.getLrmID());
			reader.setLrmName(t.getLrmName());
			reader.setLrmType(Integer.parseInt(t.getLrmType()));
			reader.setLrmState(1);
			reader.setLrmX(t.getLrmX());
			reader.setLrmY(t.getLrmY());
			reader.setRmk(t.getRmk());
			reader.setMonitorDaySecurity(t.getMonitorDaySecurity());
			reader.setDangerousMans(t.getDangerousMans());
			SecurityTraining training = new SecurityTraining();
			if(t.getSecurityTraining() != null) {
				training.setSysId(t.getSecurityTraining().getSysId());
				training.setTitle(t.getSecurityTraining().getTitle());
				training.setCreatedDate(t.getSecurityTraining().getCreatedDate());
				training.setTrainDate(t.getSecurityTraining().getTrainDate());
				training.setTrainingTypeIds(t.getSecurityTraining().getTrainingTypeIds());
				training.setUser(t.getSecurityTraining().getUser());
				training.setTrainMans(t.getSecurityTraining().getTrainMans());
				reader.setSecurityTraining(training);
			}
			reader.setLrmTime(new DateTime());
			reader.setMapID(Integer.parseInt(t.getMapID()));
			reader.setLrmRadius(t.getLrmRadius());
			reader.setPreviousReaders(t.getPreviousReaders());
			reader.setBehindReaders(t.getBehindReaders());
			reader.setOftenHoursSendSMS(t.getOftenHoursSendSMS());
			labelReadingMachineDao.save(reader);

			logs.addLog(user, "添加 读头：\""+reader.getLrmName()+"\"成功！");
			result = CommonParamter.CHECK_SUCCESS;
		} else {
			result = CommonParamter.CHECK_REPEAT;
		}
		return result;
	}

	@Transactional
	public String editReader(ReaderBean t, UserBean user) {
		String result = CommonParamter.CHECK_FAIL;
		if (StringUtils.isNotEmpty(String.valueOf(t.getId()))) {
			StringBuffer Hql = new StringBuffer("from LabelReadingMachine where 1=1 ");
			Hql.append("and id=").append(t.getId()).append("");
			List<LabelReadingMachine> list = labelReadingMachineDao.queryHql(Hql.toString());
			List<Area> listArea = areaDao.queryAll();
			if (GroupList.groupAreaOfReader(listArea).contains(String.valueOf(t.getLrmID()))) {
				return CommonParamter.CHECK_FLG;
			}
			if (CollectionUtils.isNotEmpty(list)) {
				LabelReadingMachine reader = list.get(0);
				if(reader.getLrmID()!=t.getLrmID()){
					reader.setLrmState(1);
					List<Reader_Alarm> raList = readerList("from Reader_Alarm where lrmID="+String.valueOf(reader.getLrmID()));
					if(CollectionUtils.isNotEmpty(raList)){
						for (Reader_Alarm reader_Alarm : raList) {
							raDao.delete(reader_Alarm);
						}
					}
				}
				reader.setLrmID(t.getLrmID());
				reader.setLrmName(t.getLrmName());
				reader.setLrmType(Integer.parseInt(t.getLrmType()));
				reader.setRmk(t.getRmk());
				reader.setMonitorDaySecurity(t.getMonitorDaySecurity());
				reader.setDangerousMans(t.getDangerousMans());
				SecurityTraining training = new SecurityTraining();
				if(t.getSecurityTraining() != null) {
					training.setSysId(t.getSecurityTraining().getSysId());
					training.setTitle(t.getSecurityTraining().getTitle());
					training.setCreatedDate(t.getSecurityTraining().getCreatedDate());
					training.setTrainDate(t.getSecurityTraining().getTrainDate());
					training.setTrainingTypeIds(t.getSecurityTraining().getTrainingTypeIds());
					training.setUser(t.getSecurityTraining().getUser());
					training.setTrainMans(t.getSecurityTraining().getTrainMans());
					reader.setSecurityTraining(training);
				} else {
					reader.setSecurityTraining(null);
				}
				reader.setMapID(Integer.parseInt(t.getMapID()));
				reader.setLrmRadius(t.getLrmRadius());
				reader.setPreviousReaders(t.getPreviousReaders());
				reader.setBehindReaders(t.getBehindReaders());
				reader.setOftenHoursSendSMS(t.getOftenHoursSendSMS());
				labelReadingMachineDao.update(reader);
				logs.addLog(user, "修改 读头：\""+reader.getLrmName()+"\"成功！");
				result = CommonParamter.CHECK_SUCCESS;
			} else {
				result = CommonParamter.CHECK_FAIL;
			}
		} else {
			result = CommonParamter.CHECK_FAIL;
		}
		return result;
	}

	@Transactional
	public String editReaderPosition(ReaderBean t, UserBean user) {
		String result = CommonParamter.CHECK_FAIL;
		if (StringUtils.isNotEmpty(String.valueOf(t.getLrmID()))) {
			StringBuffer Hql = new StringBuffer("from LabelReadingMachine where 1=1 ");
			Hql.append("and lrmID=").append(String.valueOf(t.getLrmID())).append("");
			List<LabelReadingMachine> list = labelReadingMachineDao.queryHql(Hql.toString());
			if (CollectionUtils.isNotEmpty(list)) {
				LabelReadingMachine reader = list.get(0);
				reader.setLrmX(t.getLrmX());
				reader.setLrmY(t.getLrmY());
				labelReadingMachineDao.update(reader);
				logs.addLog(user, "修改 读头位置：\""+reader.getLrmName()+"\"成功！");
				result = CommonParamter.CHECK_SUCCESS;
			} else {
				result = CommonParamter.CHECK_FAIL;
			}
		} else {
			result = CommonParamter.CHECK_FAIL;
		}
		return result;
	}

	@Transactional
	public String delReader(String[] arr, UserBean user) {
		String result = "3";
		LabelReadingMachine reader = new LabelReadingMachine();
		List<Area> listArea = areaDao.queryAll();
		Set<String> readSet = GroupList.groupAreaOfReader(listArea);
		String lrmName = "";
		for (int i = 0; i < arr.length; i++) {
			reader = labelReadingMachineDao.getById(Integer.parseInt(arr[i]));
			if (readSet.contains(String.valueOf(reader.getLrmID()))) {
				return CommonParamter.CHECK_FLG;
			}
			if (reader != null) {
				lrmName = reader.getLrmName();
				List<Reader_Alarm> raList = readerList("from Reader_Alarm where lrmID="+String.valueOf(reader.getLrmID()));
				if(CollectionUtils.isNotEmpty(raList)){
					for (Reader_Alarm reader_Alarm : raList) {
						raDao.delete(reader_Alarm);
					}
				}
				labelReadingMachineDao.delete(reader);
				logs.addLog(user, "删除 读头：\""+lrmName+"\"成功！");
			}
		}
		result = CommonParamter.CHECK_SUCCESS;
		return result;
	}
	
	@Transactional(readOnly = true)
	public List<Reader_Alarm> readerList(String Hql) {
		return raDao.queryHql(Hql);
	}
	
	@Transactional(readOnly = true)
	public List<LabelReadingMachine> queryAll() {
		return labelReadingMachineDao.queryAll();
	}

	@SuppressWarnings("finally")
	@Transactional(readOnly = true,isolation=Isolation.READ_UNCOMMITTED)
	public String upload(String id) {
		String result = CommonParamter.CHECK_FAIL;
		try{
			String Hql = "from LabelReadingMachine";
			List<LabelReadingMachine> readerList = labelReadingMachineDao.queryByLrmDetail(Hql);
			if(CollectionUtils.isNotEmpty(readerList)){
				ReaderModel model = new ReaderModel();
				model.setUserId(CommonParamter.userID);
				model.setPassword(CommonParamter.password);
				model.setListBean(readerList);
				CastorSerializer serializerTool = new CastorSerializer();
				ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
				serializerTool.addMappingLocation("com/sp/scmdb/webservice/mapping/mapping.xml");
				serializerTool.marshal(model, byteOutputStream, "UTF-8");
				String str = new String(byteOutputStream.toByteArray());
				UploadDataService upload=(UploadDataService )ApplicationContext.getBean("uploadService");
				result = upload.uploadReader(str);
				ReturnResponse response = (ReturnResponse) serializerTool
				.unmarshal(new ByteArrayInputStream(result.getBytes()),
						"GB2312");
				result = response.getDescription();
			}
		}catch(javax.xml.ws.WebServiceException e){
			if ("Could not send Message.".equals(e.getMessage())) {
				result = "timeOut";
			}
		}
		catch(Exception e){
			result = e.getMessage();
			log.error(e.getMessage());
		}
		finally{
			return result;
		}
	}
}
